#pragma once
#include<iostream>
#include<string.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<unistd.h>
const char* path = ".";
static int key = 666;
const char* client = "client";
const char* serve = "serve";

namespace shm{
    class myshm
    {
        private:

        void GetShm()
        {
            key_t _key = ftok(path,key);
            printf("Key generated: %d\n", _key);
            _shmid = shmget(_key,512,IPC_CREAT | 0666);
            if(_shmid == -1){
                perror("shmget");
                exit(1);
            }
             printf("GetShm successs\n");
        }

        void BuildShm()
        {
            key_t _key = ftok(path,key);
            printf("Key generated: %d\n", _key);
            _shmid = shmget(_key,512,IPC_CREAT | IPC_EXCL | 0666);
            if(_shmid == -1){
                perror("shmget");
                exit(1);
            }
            printf("BuildShm success\n");
        }
    public:

        myshm(const char* name)
        {
            if(strcmp(name,client) == 0)
                this->BuildShm();
            if(strcmp(name,serve) == 0)
                this->GetShm();
        }
       


        int getid()
        {
            return _shmid;
        }
        void* getaddr()
        {
            return _addr;
        }
        
        void Attach()
        {
            _addr = shmat(_shmid,NULL,0);
            if(_addr == (void*)-1){
                perror("shmat");
                exit(1);
            }
            printf("Attach success\n");
        }
        
        void Separte()
        {
            int n = shmdt(_addr);
            if(n == -1)
            {
                perror("shmdt");
                exit(1);
            }
            printf("Separate success\n");
        }
        
        void RmShm()
        {
            if(shmctl(_shmid,IPC_RMID,NULL)==-1)
            {
                perror("shmctl");
                exit(1);
            }
            printf("rmShm success\n");
        }
        void test()
        {
            shmid_ds sds;
        }
        struct shmid_ds* GetShmBf()
        {
            //struct shmid_ds buff;
            if(_buff == nullptr){
                _buff = new struct shmid_ds;
            }
            if(shmctl(_shmid,IPC_STAT,_buff)==-1)
            {
                perror("shmctl");
                exit(1);
            }
            printf("GetShm success\n");
            return _buff;
        }
        
        ~myshm()
        {
            if(_buff)
                delete _buff;
        }

    private:
        int _shmid;
        void* _addr;
        struct shmid_ds* _buff;
    };
}